import 'package:dio/dio.dart';
import '../../models/note_model.dart';
import '../../models/api_response.dart';

/// 笔记API服务
class NoteApiService {
  final Dio _dio;

  NoteApiService(this._dio);

  /// 创建笔记
  Future<ApiResponse<Note>> createNote(NoteCreateRequest request) async {
    try {
      final response = await _dio.post('/notes', data: request.toJson());
      return ApiResponse.fromJson(
        response.data,
        (json) => Note.fromJson(json as Map<String, dynamic>),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取笔记详情
  Future<ApiResponse<Note>> getNote(int noteId) async {
    try {
      final response = await _dio.get('/notes/$noteId');
      return ApiResponse.fromJson(
        response.data,
        (json) => Note.fromJson(json as Map<String, dynamic>),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 更新笔记
  Future<ApiResponse<Note>> updateNote(
      int noteId, NoteUpdateRequest request) async {
    try {
      final response = await _dio.put('/notes/$noteId', data: request.toJson());
      return ApiResponse.fromJson(
        response.data,
        (json) => Note.fromJson(json as Map<String, dynamic>),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 删除笔记
  Future<ApiResponse<void>> deleteNote(int noteId) async {
    try {
      final response = await _dio.delete('/notes/$noteId');
      return ApiResponse.fromJson(response.data, null);
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 获取笔记列表
  Future<ApiResponse<List<Note>>> getNotes({
    int? projectId,
    int? todoId,
    String? keyword,
    List<String>? tags,
    int page = 0,
    int size = 20,
  }) async {
    try {
      final queryParameters = {
        if (projectId != null) 'projectId': projectId,
        if (todoId != null) 'todoId': todoId,
        if (keyword != null) 'keyword': keyword,
        if (tags != null) 'tags': tags.join(','),
        'page': page,
        'size': size,
      };

      final response = await _dio.get('/notes', queryParameters: queryParameters);
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) => Note.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 搜索笔记
  Future<ApiResponse<List<Note>>> searchNotes(String keyword) async {
    try {
      final response = await _dio.get('/notes/search', queryParameters: {
        'keyword': keyword,
      });
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) => Note.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 根据标签获取笔记
  Future<ApiResponse<List<Note>>> getNotesByTags(List<String> tags) async {
    try {
      final response = await _dio.get('/notes/tags', queryParameters: {
        'tags': tags.join(','),
      });
      return ApiResponse.fromJson(
        response.data,
        (json) => (json as List)
            .map((item) => Note.fromJson(item as Map<String, dynamic>))
            .toList(),
      );
    } catch (e) {
      throw _handleError(e);
    }
  }

  /// 处理错误
  Exception _handleError(dynamic error) {
    if (error is DioException) {
      if (error.response != null) {
        final statusCode = error.response!.statusCode ?? 0;
        // 从响应体中提取错误消息
        String message = '请求失败';
        if (error.response!.data is Map<String, dynamic>) {
          final data = error.response!.data as Map<String, dynamic>;
          message = data['message'] ?? data['error'] ?? message;
        } else if (error.response!.data is String) {
          message = error.response!.data.toString();
        }
        
        // 根据状态码返回不同的异常类型
        if (statusCode == 401) {
          return const BusinessException(
            message: '认证失败，请重新登录',
            code: 401,
          );
        } else if (statusCode == 403) {
          return const BusinessException(
            message: '权限不足，无法执行此操作',
            code: 403,
          );
        } else if (statusCode >= 500) {
          return BusinessException(
            message: '服务器内部错误，请稍后重试',
            code: statusCode,
          );
        }
        
        return NetworkException(
          message: message,
          statusCode: statusCode,
          originalError: error,
        );
      } else {
        return const NetworkException(message: '网络连接失败');
      }
    }
    return NetworkException(
      message: error.toString(),
      originalError: error,
    );
  }
}